public class ReadMe {
    /**
     * 2023-4-27 数据库基础
     * 1.认识数据库？数据库的定义？
     * 2.为什么要用数据库？数据库的优势？
     * 3.MySQL数据库的应用场景？
     * 4.应用数据库？MySQL
     * 5.下载安装MySQL
     *      注意：如果安装服务的时候出现错误，则需要卸载重装
     *      卸载的时候，不建议直接删除文件夹，而是通过软件直接卸载
     *      同时，删除MySQL的注册表
     *      这时可以继续重复安装，如果还不行，则继续卸载，删除注册表，同时重启电脑
     *      如果还不行，换版本。重装电脑
     * ------------------------------------
     * 6.连接数据库：通过桌面管理工具：workbench，navcat，sqlyong，。。。
     * 7.数据库学习，主要四大分类？
     *      数据定义语言
     *      数据操作语言
     *      数据控制语言
     *      数据查询语言
     * 8.创建数据库：建议一般数据库名称和项目名称一致
     *      CREATE SCHEMA `canyin_one` ;
     * 9.tables 表
     *      views  视图
     *      stored procedures  存储过程（不建议用）：存储过程的缺点？
     *      functions 函数  方法
     * 10.创建表的时候，数据库命名建议全小写，多个单词用下划线
     *          表名和model相对于，不要加model，只是类名即可，下划线连接
     *          列名对于Java的属性
     *          数据类型对于Java的数据类型
     *     数据库的列比Java的属性多几个固定的列
     *          id：主键：可以理解为数据的唯一性，最好自动自增
     *          create_time：创建时间，
     *          update_time：更新时间 每次修改数据的时候都有一条新的记录
     *          enable：状态  1 启用 0  禁用  -1 冻结  2  可恢复
     *          remark:备注
     * 11.mysql数据类型
     *      Java       mysql
     *      Integer    int
     *      String     char  varchar  text
     *      Date（String）  TIMESTAMP|DATETIME varchar(-127-03-02 12:12:12)
     *      byte       tinyint(4)
     * 12.char  varchar  text 的区别？
     *       char   一般用于固定长度的字符：密码：因为以后秘密都要加密：特点：查询快
     *       varchar  一般用于不固定长度，且字符数量较少
     *           char(10)   就算只有一个字符，数据库还是分配10个字符的空间
     *           varchar(10)  就算只有一个字符，就分配一个空间 ，节约空间
     *       text  字符数量比较大的时候用：一般超过上万个字符
     *       一般情况下，char用于少于128个字符
     *       varchar 65535/3
     *       其他用text
     * 13.TIMESTAMP和DATETIME的区别？
     *      用时间和用varchar区别？时间可以进行排序
     *      用int和String排序肯定int快
     * 14.mysql数据库的id主键用int类型？
     *          一般建议数据库的数据大于五百万条数据或者数据大于2G的时候分库分表
     * 15.创建表：
     * CREATE TABLE `canyin_one`.`user` (
     *   `id` INT NOT NULL AUTO_INCREMENT,
     *   `username` VARCHAR(45) NOT NULL,
     *   `email` VARCHAR(100) NULL,
     *   `password` CHAR(32) NOT NULL,
     *   `create_time` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
     *   `update_time` DATETIME NULL,
     *   `enable` TINYINT(1) NULL,
     *   `remark` TEXT NULL,
     *   `height` DECIMAL(3,2) NULL,
     *   PRIMARY KEY (`id`),
     *   UNIQUE INDEX `username_UNIQUE` (`username` ASC) VISIBLE);
     * 16.MySQL 不区分大小写
     * 17.数据库删除：DROP DATABASE `canyin_one`;
     * 18.新增列
     *      ALTER TABLE `canyin_one`.`user`
     * ADD COLUMN `weight` DECIMAL(5,2) NULL DEFAULT 0 AFTER `height`;
     *
     * ALTER TABLE `canyin_one`.`user`
     * CHANGE COLUMN `remark` `remarker` CHAR(10) NULL DEFAULT NULL AFTER `weight`;
     * 19.删除 列
     *  ALTER TABLE `canyin_one`.`user`
     * DROP COLUMN `remark`;
     * 20.数据操作语言
     *      新增数据
     *      INSERT INTO `canyin_one`.`user` (
     * `username`, `email`, `password`,  `update_time`, `enable`, `remark`, `height`, `weight`) VALUES (
     * '11', '1', '1',  sysdate(), '1', '1', '1', '1');
     * 得到系统时间：now(),sysdate();
     * 21.建议以后数据库不要存在null值：后面有些函数取查询的时候会跳过null
     * 22.选择数据库：use canyin_one;
     * 23.修改数据库表的内容 update  表名  set  列名="值" where id=2;
     * UPDATE `user` SET `username` = '22', `email` = '2', `password` = '2',
     * `create_time` = now(), `update_time` = '2023-02-27 15:04:32',
     *  `enable` = '2', `remark` = '2', `height` = '2', `weight` = '2' WHERE (`id` = '4');
     * 24.删除：
     * delete  from `user` where id=3;
     *
     */
    /**
     * 2023-5-4 数据库查询
     * 1.表里面的列，对应的是第二阶段的JavaBean，第三阶段的model
     * 2.E-T图
     * 3.第四阶段创建表的时候，只是每个表几个固定的列，id,create_time,update_time,enable,remark;
     * 4.三大范式：五大约束
     * 5.-- user;
     * -- user_address;
     * -- 对于一对多 关联
     * -- 1. 可以在多的地方表里面添加一个一的id
     * -- user(id,name,...)  user_address(id,address,user_id,....)
     * -- 2.添加第三张表，以后对于每个对象来说，不应该有对方的属性，
     * -- user_user_adderss_ralation 关联表
     * 6.建议以后，创建数据库的时候，列有一个默认值，如果是字符用空，如果是数字用0
     * 7.数据库的账号权限配置
     * 8.数据库的内容导入导出
     * 9. 省市区地址表 --  aa(id,name,p_id,)
     *   -- 1  四川   0
     *   -- 2  北京   0
     *   -- 3   成都   1
     *   -- 4  南充    1
     *   -- 5   武侯区  3
     *   -- 6   红牌楼   5
     * 10.查询语言
     * 11.以后禁用in或者not in，因为会遍历整个数据库表
     * select * from product where normal_price>=0 && normal_price<=10;
     * select * from product where normal_price between 0 and 10;
     * select * from product where id in (1,22,83);
     * select * from product where id not in (1,22,83);
     * select * from product where name like '%回%';
     * select * from product where name = '回';
     * select * from product where name like '_回__';
     * -- 正则表达式
     * select * from product where name regexp '[锅吧肥]肉';
     * 12.[啊，吧，从，的，额]只能取里面的一个
     * 13.[^a,e,b,c]非
     * 14.[a-Z]错的
     *      [A-z]对的  对应ascii码
     *      [0,9]
     *      [0-9]
     *      [8,9]
     * 15.查询的时候，一般以最新的时间进行排序
     * select * from product order by id desc;
     * -- desc 降序  asc默认 升序
     * select * from product order by name asc,price desc;
     * -- 先以name排序，如果name一样，则再以price进行排序
     *
     * select * from product order by name desc,price;
     * 16.分组,将相同的分为一个组
     *      select name from product group by name,price;
     *      group by 后面的列包含from前面的列
     *      select name,price from  product  group by name,price having price>100;
     *      having 相当于where条件，只不过只能跟在group by之后，比where更快
     * 17.分页的目的就是更少更方便的查询数据
     *      每一页显示10条数据size，想显示第三页page
     *      select * from product limit (page-1)*size,size;
     * 18.sql关键字顺序
     *      select -->from-->where -->group by-->having-->order by -->limit
     * 19.子查询
     *      select * from product
     *      where price=(
     *      select max(price) from product)
     *
     *      select * from product order by price desc limit 1;
     */
    /**
     * 2023-5-5 Java连接数据库
     * 用户新增为例
     * 1.创建项目
     * 2.创建所需要的包：三层架构
     * 3.model  和数据库表相对于
     * 4.servlet
     * 5.service
     * 6.dao
     * 7.JDBC：连接数据库需要用到jdbc
     *      1.加载驱动：引入jar包
     *      2.得到连接，修改用户名，密码，地址和数据库名
     *      3.编译sql
     *      4.执行sql
     *      5.返回执行结果
     *      6.关系连接
     * 8.如果出现包没有找到，可能的原因是没有将包放入到根目录，需要put into root
     * ------------------------
     * 9.修改：
     *      1.servlet
     *      2.service
     *      3.dao
     * 10.删除
     * 11.注意：sql语句每个单词前后建议都写一个空格
     * 12.sql语句里面除了数字不要引号，其他都要引号，建议所有都用引号。函数不用引号
     * 13.以后字符串方法调用将""写在前面 "".equals(model.getName())
     * -----------------------------------------------
     *
     */
    /**
     * 2023-5-6 Java后台封装
     * 1.复习昨天知识点
     *      1）创建项目
     *      2）创建包，配置tomcat
     *      3）引入jar包：servlet，Lombok，fastjson，mysql
     *      4）以用户新增为例
     *           1：model 和表列一致
     *           2：servlet  给前端一个接口地址：webservlet注解
     *                  五大步骤
     *           3：service  写逻辑代码的地方
     *           4：dao
     *                  编写sql语句
     *                  调用JDBC
     *                  解析结果集
     *           5：JDBC（工具，直接调用即可）
     * 2.产品
     * 3.以后文件一定不能直接放在数据库（数据库很贵）
     * 4.服务器就是一台电脑（虚拟机）
     * 5.layui:
     * 6.dto:返回给前端的数据
     *
     */
    /**
     * 2023-5-8 文件上传
     * 1.复习
     *      1：产品CRUD
     *      2.提取了一个父类：普通的父类，--抽象发父类--接口--子接口对父接口的扩展
     *      3：泛型：
     *      4.统一返回给前端的数据格式：JSON对象，数据格式应该由Java后端决定（建议商量）
     * 2.文件上传时：文件的地址不能用绝对路径（有盘符），但是可以是绝对地址（“/a/b/d/a.jpg”）
     * 3.文件上传，不能让用户直接输入地址，而应该给用户一个操作的按钮，通过代码返回一个地址（建议用绝对地址）
     * 4.怎么做？上传文件时，应该将文件保存到某一个地址（IO流）
     * 5.Java后台怎么接收前端传递过来的流？
     *      1：doPost
     *      2：通过req得到前端的值，然后进行封装List
     *      3：建议文字和图片单独请求List<File>
     *      4:遍历：把文件保存到某个地方：item
     *      5：创建文件夹和文件的路径path
     *      6.将文件进行保存：save(item,path);
     *      7.将path返回给调用者（前端）
     *      8.文件的复制(会)
     * 6.一般情况下，拿到路径是指out里面的路径,所有编译过后的代码都在out里面
     * 7.以后回设计到清除缓存：清除缓存的时候一般要删除out和target文件，
     * 8.将out里面的文件复制一份到web目录下：（暂时,正式上线后不需要）
     */
    /**
     * 2023-5-9 js基础
     * 1.js的数据类型：数字，字符，布尔，对象，数组 null
     * 2.变量的定义：let   const
     * 3.方法的定义：function  name(num){console.log(11)};
     * 4.java   ==  equals
     * 5.js     ===   ==
     * -----------------------------------
     * 6.验证码
     * 7.页面点击登录按钮，应该拿到所有的数据，并传递给Java后台
     * 8.以后都是用js传递：Ajax
     * 9.提交之前需要做验证:
     * --------------------------
     * 登录逻辑：
     *  前端：
     *  用户输入：用户自定义验证
     *  点击按钮：通过ajax访问Java后台
     *  根据响应的逻辑进行处理
     *  后台：和以前一样
     */
    /**
     * 2023-5-10 用户管理
     * 1.在Java后端，如果在其他地方要拿到值，req，session，application
     * 2.在web前端：如果要在其他页面得到值，也需要将值放入一个容器，session，application
     * 3.在用户登录成功以后，将用户名存入session
     * 4.每一个js最好都写一个页面加载完成执行里面的代码$(function () {
     * 5.最好所有的id都唯一，不相同
     * 6.js的定时器
     * ----------------------
     * 7.查询
     *      1）复制table的html
     *      2）复制编辑和删除的html
     *      3）复制对应的js
     * 8.监听按钮的时候，需要禁止刷新页面
     * 9.以后查询数据库的时候禁止使用*
     * 10.删除：
     *      1）在html添加删除的监听
     *      2)js里面去拿到监听
     *      3）提示是否需要删除
     *      4）调用Ajax进行删除即可
     * 11.增加：
     *      1）写html表单
     *      2）监听提交按钮
     *      3）自定义验证
     *      4）得到所有表单的值：复选框要自己写
     *      5）调用Ajax
     *
     */
    /**
     * 2023-5-11 用户编辑和模糊查询
     * 1.前端页面步骤
     *      1）html页面
     *      2）js文件：
     *          1）页面加载完成执行里面的代码
     *          2）加载layui的模板
     *          3）有用户输入就需要自定义验证
     *          4）有用户操作就有按钮监听
     *              1：将里面的值变成自己的 data = data.field;
     *              2：如果有拿不到的值，需要手动去拿
     *              3：如果不是字符串，则需要转换为字符串
     *          5）Ajax调用Java后台的注解地址
     *          6）根据响应的值进行逻辑处理
     * 2.密码修改
     *      1：html页面
     *      2：js
     *          1）页面加载完成执行里面的代码
     *          2）加载模板
     *          3）拿到点击的行数据，跳转到修改密码页面
     *          4）将行数据转换为json对象，并赋值给页面
     *          5）将id进行隐藏
     *          6）提交ajax到Java后台
     * 3.编辑
     *      1：html页面
     *      2:js
     *          1)页面加载完成执行里面的 代码
     *          2）加载layui模板：多加一个日期
     *          3）得到用户的值
     *          4）将值赋值到表单：两种方式
     *          5)点击提交编辑按钮之前需要自定义验证
     *          6）调用修改的Ajax
     *      3:一般情况下不直接将查询页面的数据直接传递到修改页面
     *          同第三阶段的修改：
     *          1）点击修改按钮，拿到id
     *          2）根据id在数据库里面查询
     *          3）查询完后赋值给表单
     * 4.页面赋值的时候，单选和复选是赋值不上去
     * --------------------------------------
     * 5.模糊查询注意规则
     *      1）用户会想到看你的查询列表，有哪些列名就应该有哪些模糊查询条件
     *      2）如果是日期，可能用户会想到查询日期之前，日期之后，或者日期之间的信息
     *      3）如果是数字，可能用户会想查询小数某个数字的数据，大于某个数字的数据，或者之间的数据
     * 6.如果数据库里面的某一列有数组，则用find_in_set进行查询
     * --------------------------------------------------
     *
     */
    /**
     * 2023-5-12 产品CRUD
     * 1.编辑：
     *      页面之间的数据加载
     *      1.直接将数据存在session
     *          如果存对象，则需要将对象转换为JSON.stringify(data)
     *          在另一个页面需要将对象拿出来，再次转换为json对象JSON.parse(user)
     *      2.将id传递到另一个页面
     *          1）得到当前传递过来的id let userId = sessionStorage.getItem("userId");
     *          2）根据id从数据库里面去查询所需要的数据findById(userId);
     *          3）将值赋值给表单： setData(res.data);
     * 2.产品查询：
     *      1）修改index页面
     *      2)创建product-list.html
     *      3）创建product-list.js
     *      4）修改dao层的sql:添加了菜系列
     * 3.产品新增
     *      1）创建页面product-add.html
     *          修改页面
     *          菜系应该是下拉菜单，数据应该来源于数据库
     *      2)创建js文件
     * 4.如果是菜系管理，则需要查询所有的菜系
     * 5.如果是新增，应该将正常的菜系查询出来，不然会将产品和不要的菜系相关联
     * 6.文件上传
     * 7.产品描述：富文本
     *      1:引入js
     *      2：创建富文本的js
     *      3：html代码
     *      4.富文本取值：data.content = editor.txt.html();
     * 8.编辑：
     *      1：html页面：引入js
     *      2：创建updatejs
     *      3：修改update.js
     *          页面加载顺序：
     *          1）页面加载完成执行里面的代码
     *          2）layui加载模板
     *          3）文件上传和富文本编辑器的js
     *          4）加载菜系的列表
     *          5）根据id查询当前产品，并赋值给当前的页面
     *          6)点击提交按钮进行编辑
     * ---------------------------------------
     * 总结：
     *  1：前端
     *      1）html页面
     *          富文本和文件上传
     *      2）创建js
     *          1-页面加载完成执行里面的代码
     *          2-加载layui模板
     *          3-富文本和文件上传的js
     *          4-如果有数据从数据库里面来，则加载数据库里面的数据，并赋值到html页面
     *          5-用户输入数据，并自定义验证
     *          6-点击提交按钮调用ajax进行操作
     *  2：后端
     *      1）model
     *      2）servlet  五大步骤
     *      3）service 逻辑服务
     *      4）dao  sql  并解析结果集
     *      5）JDBC
     *
     *
     *
     */
    /**
     * 2023-5-15 安全认证
     * 1.在前端页面不能直接访问某个页面，必须要登录才可以
     *      1）当用户访问某个页面的时候，需要进行登录判断
     *      2）如果登录成功，则可以进行操作，否则直接返回登录页面
     *      3）在加载页面的时候直接进行判断
     *      4)如果有很多页面都需要判断，则需要提供一个公共的js
     *      5)前端也是，将数据标识符放入session
     *      6）怎么做？
     *      ----------
     *      common.js
     * 2.在用户直接访问Java后台接口时，也应该判断是否以及登录;
     *      MyFilter
     * 3.Java servlet  三大核心构建
     *      1.servlet
     *      2.filter
     *      3.listener
     * 4.对于后台session来说，每个用户访问时，都必须判断是不同的用户
     *      1. req.getSession().setAttribute(username, username);
     *      2.每次前端访问后台时，都应该将前端的用户名传递到Java后台
     * -------------------------------------------------
     * 对于认证：
     *  前端
     *  后端
     *  在某一给地方存一个标识符：表示以及登录成功
     *  在下一次访问时，判断当前标识符是否存在
     *  如果不存在，则跳转到登录页面即可
     *
     */
    /**
     * 2023-5-16
     * 1.预加载，懒加载
     * 2.redis默认有16个数据库，默认选择第一个，下标是0
     * 3.如果做了一个秒杀事件，那么用户访问页面的时候，有很多人
     * 4.第一个人访问数据库，后面的人就不能访问数据库了，
     * 5.第一个人访问数据后，应该将数据存到某个地方（redis）
     * 6.后面的人再次访问时，首先查看redis里面是否有数据，
     * 7.如果有，则直接将redis里面的数据拿到，并封装到对象，然后返回给前端
     * 8.如果没有，则直接取数据库，然后在存入redis
     * -------------------------------------
     * 思路：
     *      1）引入jar包
     *      2）写逻辑service
     *      3）判断是否有值
     * ----------------------
     * 1.如果是字符串，再次对相同的key值进行赋值，则后面的会覆盖前端的值
     * 2.如果是集合，再次对相同的key值进行赋值，则后面的值会追加到以前的集合
     * 3.如果管理员对数据进行跟新(新增，修改，删除)后，则需要删除redis里面的key值
     */
}
